/*
 * Manuscript class represents a Manuscript.
 */
package conference;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Manuscript class represents a manuscript.
 * @author Allison Graham
 * @version 1.09
 */
public class Manuscript extends AbstractDocument {
    private Status myStatus = Status.UNDECIDED;  /**The current status.*/
    private List<Review> myReviewList; /**A collection of Reviews.*/
    private File myFile; /**A possible file for the contents of the text.*/

    /**
     * Returns an instance of a manuscript with the given 
     * Author, the given file, and the status set at 
     * undecided.
     * -precondition: the File != null.
     * -precondition: theAuthor != null.
     * -postcondition: super.getCreator() == theAuthor.
     * -postcondition: myFile == theFile.
     * -postcondition: myTitle == theTitle.
     * -postcondition: myStatus == Status.UNDECIDED.
     * -postcondition: myReviewList.size() == 0.
     * @param theAuthor The author of this manuscript.
     * @param theFile The file containing the text of this manuscript.
     * @param theTitle The title of the manuscript document.
     */
    public Manuscript(final Author theAuthor, final File theFile, final String theTitle){
        super(theTitle, getMyFileContents(theFile), theAuthor);
        myStatus = Status.UNDECIDED;
        myReviewList = new ArrayList<Review>();
        myFile = theFile;
    }
    
    public Manuscript(final Author theAuthor, final String theFileContents, 
    		final String theTitle) {
    	super(theTitle, theFileContents, theAuthor);
    	myStatus = Status.UNDECIDED;
    	myReviewList = new ArrayList<Review>();
    	myFile = null;
    }
    
    
     /**
     * Constructor that creates a copy with the new status.
     * -precondition: none
     * -postcondition: myTitle == theManuscript.getTitle();
     * -postcondition: myFile == theManuscript.getFile();
     * -postcondition: super.getCreator() == theManuscript.getAuthor();
     * -postcondition: myStatus == theStatus;
     * -postcondition: myReviewLisst == myManuscript.getReviews();
     * @param theManuscript The manuscript to copy.
     * @param theStatus The status of the new copy.
     */
    public Manuscript(final Manuscript theManuscript, 
    		final Status theStatus) {
        super(theManuscript.getTitle(), 
        		theManuscript.getFileContents(),
                theManuscript.getAuthor());
        myStatus = theStatus;
        myReviewList = 
        	new ArrayList<Review>
        (theManuscript.getReviews());
        if (theManuscript.getFile() != null) {
        	myFile = theManuscript.getFile();
        }
        else {
        	myFile = null;
        }
    }
    
    /**
     * Constructor that creates a copy with an additional review.
     * -precondition: none
     * -postcondition: myTitle == theManuscript.getTitle();
     * -postcondition: myFile == theManuscript.getFile();
     * -postcondition: myAuthor == theManuscript.getAuthor();
     * -postcondition: myReviewList.size() == theManuscript.getReviews().size() + 1
     * -postcondition: mySatus = theManuscript.getStatus;
     * @param theManuscript The Manuscript to copy.
     * @param theReviews The Reviews to add to the new Manuscript.
     */
    public Manuscript(final Manuscript theManuscript,
    		final List<Review> theReviews) {
    	super(theManuscript.getTitle(), 
    			theManuscript.getFileContents(), 
    			theManuscript.getAuthor());
    	myReviewList = 
    		new ArrayList<Review>(theReviews);    
    	myStatus = theManuscript.getStatus();
    	if (theManuscript.getFile() != null) {
        	myFile = theManuscript.getFile();
        }
        else {
        	myFile = null;
        }
    	
    }
    
    /**
     * Returns the current status of this manuscript.
     * -precondition: none
     * -postcondition: none
     * @return The status of this manuscript.
     */
    public Status getStatus() {
        return myStatus;
    }

    /**
     * Returns the Author for this manuscript.
     * -precondition: none
     * -postcondition: none
     * @return The author for this manuscript.
     */
    public Author getAuthor() {
        return (Author) super.getCreator();
    }
    
    /**
     * Returns the reviews for this manuscript.
     * -precondition: none
     * -postcondition: none
     * @return Returns the reviews as List<Review>
     */
    public List<Review> getReviews() {
    	//Copy reviews into a new list to return.
    	return new ArrayList<Review>(myReviewList);
    }
    
    /**
     * Returns the number of Reviews contained with this
     * manuscript.
     * -precondition: none
     * -postcondition: none
     * @return Number of reviews as int.
     */
    public int getNumberOfReviews() {
    	return myReviewList.size();
    }
    
    /**
     * Returns the number of completed reviews for this
     * manuscript.
     * -precondition: none
     * -postcondition: none
     * @return Number of completed reviews as int.
     */
    public int getNumberOfCompletedReviews() {
    	int numComplete = 0;
    	for(Review r : myReviewList) {
    		if(r.isComplete()) {
    			numComplete++;
    		}
   		}
    	return numComplete;
    }    
    
    /**
     * Returns the file that contains the text for this manuscript is it exists.
     * @return File as File or null if not existing.
     * @author Allison Graham
     */
    public File getFile() {
    	return myFile;
    }
    
    /**
     * Returns a string representation of the file contained within 
     * this document
     * @return The file contents in this document as String.
     * @throws FileNotFoundException 
     */
    private final static String getMyFileContents(final File theFile){
    	 StringBuilder contents = new StringBuilder();    
    	 try {
    		 //use buffering, reading one line at a time
    		 //FileReader always assumes default encoding is OK!
    		 BufferedReader input =  new BufferedReader(new FileReader(theFile));
    	     try {
    	    	 String line = null; //not declared within while loop
    	    	 /*
    	    	  * readLine is a bit quirky :
    	    	  * it returns the content of a line MINUS the newline.
    	    	  * it returns null only for the END of the stream.
    	    	  * it returns an empty String if two newlines appear in a row.
    	    	  */
    	    	 while (( line = input.readLine()) != null){
    	    		 contents.append(line);
    	    		 contents.append(System.getProperty("line.separator"));
    	    	 }
    	     }
    	     finally {
    	    	 input.close();
    	     }
    	 }
    	 catch (IOException ex){
    		 ex.printStackTrace();
    	 }
    	 
    	 return contents.toString();
    }
}